import 'package:flutter/material.dart';


extension Consumer on BuildContext {

  T watch<T extends ChangeNotifier>() {
    return Provider.of<T>(this, true);
  }

  T read<T extends ChangeNotifier>() {
    return Provider.of<T>(this, false);
  }

}

class Provider<T extends ChangeNotifier> extends StatefulWidget {

  final Widget Function(BuildContext) builder;

  final T changeNotifier;

  const Provider({
    super.key,
    required this.builder,
    required this.changeNotifier
  });

  @override
  State<Provider> createState() => _ProviderState<T>();

  static T of<T extends ChangeNotifier>(BuildContext context, [bool watch = true]) {
    print("正在读取Provider");
    if(watch) {
      return context.dependOnInheritedWidgetOfExactType<_InheritedProviderWidget<T>>()!
          .changeNotifier;
    } else {
      return context.getInheritedWidgetOfExactType<_InheritedProviderWidget<T>>()!
          .changeNotifier;
    }
  }

}

class _ProviderState<T extends ChangeNotifier> extends State<Provider> {
  @override
  Widget build(BuildContext context) {
    return ListenableBuilder(
        listenable: widget.changeNotifier,
        builder: (a, b) {
          return _InheritedProviderWidget<T>(
            changeNotifier: widget.changeNotifier as T,
            child: Builder(
              builder: (context) => widget.builder(context),
            ),
          );
        });
  }
}


class _InheritedProviderWidget<T extends ChangeNotifier> extends InheritedWidget {

  final T changeNotifier;

  _InheritedProviderWidget({
    required super.child,
    required this.changeNotifier
  }) {
    print('构建_InheritedProviderWidget 完成');
  }

  @override
  bool updateShouldNotify(covariant InheritedWidget oldWidget) {
    print('updateShouldNotify');
    return true;
  }

}